package com.hfzy.ihk.web.ivr.context;

/**
 * Created by Administrator on 2018/9/11.
 *
 * @author wws
 */

import com.alibaba.fastjson.JSON;
import com.hfzy.ihk.common.eventSocket.constant.EventSubClassName;
import com.hfzy.ihk.common.eventSocket.context.EventSocketInit;
import com.hfzy.ihk.common.eventSocket.enums.EventName;
import com.hfzy.ihk.common.util.date.DateUtils;
import com.hfzy.ihk.web.ivr.biz.CallIntoBiz;
import com.hfzy.ihk.web.ivr.biz.FreeswitchAsrCallSpeakStateBiz;
import com.hfzy.ihk.web.ivr.biz.FreeswitchAsrCallStateBiz;
import org.freeswitch.esl.client.transport.event.EslEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static com.hfzy.ihk.common.eventSocket.enums.EventName.*;

@Configuration
public class EventSocketInitBean extends EventSocketInit {

    private static final Logger logger = LoggerFactory.getLogger(EventSocketInitBean.class);

    private static ConcurrentHashMap<String,String> localConnection =new ConcurrentHashMap<String, String>(10000); //用于储存本机通话,防止多个call服务重复发生状态

    private static ConcurrentHashMap<String,String> customerConnection =new ConcurrentHashMap<String, String>(10000); //用于记录客户是否在说话

    private static ConcurrentHashMap<String,String> robotConnection =new ConcurrentHashMap<String, String>(10000); //用于记录机器人是否在播放录音

    private static ConcurrentHashMap<String,List> recordFileUrlMap = new ConcurrentHashMap<>(10000);//播放录音文件url

    @Value("${freeswitch.host}")
    private String host;
    @Value("${freeswitch.port}")
    private int port;
    @Value("${freeswitch.password}")
    private String password;

    @Autowired
    CallIntoBiz callIntoBiz;

    @Autowired
    FreeswitchAsrCallStateBiz freeswitchAsrCallStateBiz;

    @Autowired
    FreeswitchAsrCallSpeakStateBiz freeswitchAsrCallSpeakStateBiz;

    protected boolean hasSessionId(String sessionId,EslEvent event){
        if (!hasCall(sessionId)){

            Map<String, String> eventHeaders = event.getEventHeaders();

            String eventName = eventHeaders.get("Event-Name");

            //呼入
            if (CHANNEL_CREATE== EventName.fromName(eventName)&&"inbound".equals(eventHeaders.get("Caller-Direction"))&&"external".equals(eventHeaders.get("variable_sofia_profile_name"))){

                logger.info("外部呼入：{}",JSON.toJSONString(eventHeaders));
                callIntoBiz.freeswitchCallIntoOpt(event);
            }else{

                logger.info("本次通话不是由此服务发起,所以不处理,sessionId:"+sessionId);
                return false;
            }

        }
        return true;
    }

    @Override
    protected void stateProcessing(EslEvent event) {
        String eventName = event.getEventHeaders().get("Event-Name");
        switch (EventName.fromName(eventName)){
            case CHANNEL_PROGRESS:
            case CHANNEL_ANSWER:
            case CHANNEL_HANGUP:
            case CHANNEL_HANGUP_COMPLETE:
                freeswitchAsrCallStateBiz.dealCallState(event);
                break;
            case PLAYBACK_START:
            case PLAYBACK_STOP:
                freeswitchAsrCallSpeakStateBiz.dealAsrCallSpeakState(event);
                break;
        }
    }

    @Override
    protected void eventProcessing(EslEvent event) {

        Map<String, String> eventHeaders = event.getEventHeaders();

        String eventName = event.getEventHeaders().get("Event-Name");

        Long start = System.currentTimeMillis();

        logger.info("入队时间：" + (System.currentTimeMillis() - start));

        switch (EventName.fromName(eventName)) {
            case CUSTOM:
                String subclass = eventHeaders.get("Event-Subclass");
                switch (subclass){
                    //case EventSubClassName.VAD_START:
                    //case EventSubClassName.VAD_STOP:
                    case EventSubClassName.ALIBABA_ASR_ON_SENTENCE_BEGIN:
                    case EventSubClassName.ALIBABA_ASR_ON_SENTENCE_END:
                        freeswitchAsrCallSpeakStateBiz.dealAsrCallSpeakState(event);
                        break;
                    /*case EventSubClassName.ALIBABA_ASR_ON_SENTENCE_END:
                        freeswitchAsrCallStateBiz.handleAlibabaAsr(event);
                        break;*/
                    case EventSubClassName.DIAL_GATEWAY_NOT_REGISTER:
                        logger.error("网关未注册:gatewayUser：{}，sessionId：{}",eventHeaders.get("gatewayUser"),eventHeaders.get("sessionId"));
                        freeswitchAsrCallStateBiz.handleLineBusy(event);
                        break;
                    case EventSubClassName.DIAL_LINE_BUSY:
                        logger.warn("线路忙:sessionId：{}",eventHeaders.get("sessionId"));
                        freeswitchAsrCallStateBiz.handleLineBusy(event);
                        break;
                    case EventSubClassName.ALIBABA_ASR_ON_TRANSCRIPTION_COMPLETED:
                        logger.info("-----语音识别结束标志事件------");
                        freeswitchAsrCallStateBiz.handleSpeechRecognitionEnd(event);
                        break;
                    default:
                        logger.error("未处理的自定义消息：subclass:{},sessionId:{}",subclass,eventHeaders.get("sessionId"));
                }
                break;
            case HEARTBEAT:
                logger.info("心跳------------》时间：{}", DateUtils.formatDate(new Date()));
                break;
            default:
                //logger.warn("没有此事件类型:" + eventName);
        }

    }

    @Override
    protected String getEvents() {
        return "CHANNEL_CREATE CHANNEL_PROGRESS CHANNEL_ANSWER CHANNEL_HANGUP PLAYBACK_START PLAYBACK_STOP CHANNEL_HANGUP_COMPLETE HEARTBEAT " +
                "CUSTOM alibaba_asr::onSentenceBegin alibaba_asr::onSentenceEnd alibaba_asr::onTranscriptionCompleted dial::gateway_not_registered dial::lineBusy";
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * 将此call服务的通话添加到call服务的Map中
     */
    public void addCall(String callSessionId){

        localConnection.put(callSessionId,"busy");

    }

    public boolean hasCall(String callSessionId){

        return localConnection.containsKey(callSessionId);
    }

    /**
     * 清除通话
     */
    public void clearCallMap() {
        localConnection.clear();
        customerConnection.clear();
        robotConnection.clear();
        recordFileUrlMap.clear();
    }

    public static ConcurrentHashMap<String, String> getLocalConnection() {
        return localConnection;
    }

    public static ConcurrentHashMap<String, String> getCustomerConnection() {
        return customerConnection;
    }

    public static ConcurrentHashMap<String, String> getRobotConnection() {
        return robotConnection;
    }

    public static ConcurrentHashMap<String, List> getRecordFileUrlMap() {
        return recordFileUrlMap;
    }


}